﻿/**
 *      设备基类
 */
#pragma once
#include <ossObject.h>
#include <ossString.h>
#include <ossDll.h>
#include <ossStdlib.h>
#include <ossMsgBase.h>
#include <hash/ossStringHashKey.h>
#include <ossTaskScheduler.h>
#include "labelDriverDef.hpp"


//#define LD_MALLOC_CLASSOBJ(OBJ) (\//这种定义方式无法编译通过
//		char* ptr = Malloc(sizeof(OBJ)),\
//		ptr != NULL ? (new(ptr) OBJ()),NULL)

//(new(Malloc(sizeof(OBJ))) OBJ())//这种定义方式有风险，malloc可能返回为NULL

//最终采用这种声明方式
/**
 *		框架分配对象
 *@OBJ		需要分配的变量类型
 *@var		自动创建的变量名，为指针类型
 *@notes	自动定义变量var,然后分配内存并初始化
 */
#define LD_MALLOC_CLASSOBJ(OBJ,var) OBJ* var = (OBJ*)LdMalloc(sizeof(OBJ));\
										if(var){\
											new(var) OBJ();\
										}

#define LD_MALLOC_CLASSOBJ_PARAM(OBJ,var,OBJparam) OBJ* var = (OBJ*)LdMalloc(sizeof(OBJ));\
	if(var){\
	new(var) OBJ OBJparam;\
	}

#define LD_MALLOC_BUF(iSize) LdMalloc(iSize)

/**
 *		释放
 */
#define LD_FREE_CLASSOBJ(OBJ,ptr) (ptr->~OBJ(), LdFree(ptr))

#define LD_FREE_BUF(ptr) LdFree(ptr)

typedef OssVersion* (*DriverGetVersionFun)();

class LabelDeviceBase :public OssMsgBase
{
public:
    /**
     *      构造接口
     *@pParent  父设备，所有实例必须传入父设备以便明确接口
     */
    LabelDeviceBase(LabelDeviceBase* pParent);
    LabelDeviceBase(LabelDeviceBase* pParent,
        DeviceReportFun			fDeviceReport,
        LabelDeviceBase*        lpReportContext,
        LdMallocFun			    mallocFun,
        LdFreeFun				freeFun,
        LPVOID					memoryContext,
        LdCreateAndFreeNotify     createAndFreeNotify,
        LPVOID                    createAndFreeNotifyContext,
        HandleDeviceRequestFun      handleDeviceRequestFun,
        LPVOID                      handleDeviceRequestContext
    );
    virtual ~LabelDeviceBase(void);

    /**
    *      初始化实例的方法
    *@pcDeviceId       设备ID
    */
    virtual BOOL DeviceInit(OssJson& initJson);

    /**
     *      逆初始化方法
     */
    virtual BOOL DeviceDeinit();

    /**
     *      启动实例
     */
    virtual BOOL DeviceStart();

    /**
     *      停止实例
     */
    virtual BOOL DeviceStop();

    /**
     *      attach to specifiy device
     */
    void AttachTo(LabelDeviceBase* toDevice);

    /**
     *      detach
     */
    void Detach();

    /**
     *      free all attached devices
     */
    BOOL FreeAllAttachDevices();
    
    /**
     *      发送请求
     *@requestParam     请求参数
     *@return           成功返回TRUE
     *                  失败返回 FALSE
     */
    virtual BOOL SendReqest(OssJson& requestParam);

    /**
     *      发送回应
     */
    virtual BOOL SendResponse(OssJson& responseParam);

    /**
     *      取消设置参数的任务
     *@lpResultContext      HandleServerReqest的上下文参数
     *@return               取消成功返回TRUE,否则返回FALSE
     *@NOTES                取消任务是因为请求的上下文可能会被释放，需要将与本请求相关所有请求任务释放。
     *                      如果将HandleServerReqest方法实现成同步方法，则CancelRequest可以不实现。
     */
    virtual BOOL CancelRequest(OssJson& cancelParam);

    /**
     *      更新UI
     */
    virtual BOOL UpdateUi(OssJson& requestParam);

    /**
     *      获取驱动版本信息
     */
    virtual OssVersion *GetDriverVersion();

    /**
     *      获取设备ID
     */
    char *GetDeviceId();

    //设置设备ID
    void SetDeviceId(const char* pcDeviceId);

    /**
     *      日志输出
     */
    void WriteLog(LogPriority priority,const char* format,...);
    void WriteLog(const char* format,...);
    

	/**
	 *		分配内存
	 */
	void* LdMalloc(int iSize);

	/**
	 *		释放内存
	 */
	BOOL LdFree(void* ptr);


    /**
     *      设备信息上报
     *@return       无
     */
    void DeviceReport(LdDataType tDataType, OssJson& reportData);

	/**
	 *		获取指定设备的设备
	 */
	virtual LabelDeviceBase* GetDeviceById(const char* pcDeviceId);

    /**
     *      设置获取版本信息的回调接口
     */
    void SetVersionFun(DriverGetVersionFun pFun);

    //声明消息映射表
    DECLARE_OSS_MESSAGE_MAP()

protected:

	/**
	 *		根据设备ID获取设备
	 */
	int OnGetDeviceById(WPARAM wParam,LPARAM lParam);

	/**
	 *		获取设备的版本信息
	 */
	int OnGetDeviceVersion(WPARAM wParam,LPARAM lParam);

    void WriteLogEx(LogPriority priority, const char* format, va_list a_args);
protected:
	 LdStatus				m_status;
private:
    char					m_acDeviceId[DEVICE_BASE_ID_LEN];
    DeviceReportFun			m_fDeviceReport;
    LabelDeviceBase*		m_lpReportContext;
   
	//内存管理相关的接口	
	LdMallocFun			    m_mallocFun;
	LdFreeFun				m_freeFun;
	LPVOID					m_memoryContext;	

    //实例管理相关接口，用于处理设备的创建与释放
    LdCreateAndFreeNotify      m_createAndFreeNotify;
    LPVOID                      m_createAndFreeNotifyContext;
    OssListNode                 m_attachedList;     //贴到本实例的设备，当本实例释放时需要将其一块释放。
    OssListNode                 m_attachNode;

    HandleDeviceRequestFun      m_handleDeviceRequestFun;
    LPVOID                      m_handleDeviceRequestContext;

    DriverGetVersionFun         m_getVersionFun = nullptr;//获取版本信息的专用通道
};

